package service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import to.ProdutoPorQuantidadeTO;
import util.UtilData;
import dao.GenericDAO;
import dao.ItemCompraDAO;
import dao.ItemVendaDAO;
import dao.ProdutoDAO;
import entity.GrupoProduto;
import entity.ItemCompra;
import entity.ItemVenda;
import entity.Produto;
import enumeration.PeriodoEnum;

/**
 * 
 * @author vinicius.silva
 * @version 1.0
 */
@Service
public class ProdutoServiceImpl extends ManutencaoServiceImpl<Produto>
		implements ProdutoService, Serializable {

	private static final long serialVersionUID = 2892712219712130868L;

	@Autowired
	private ProdutoDAO produtoDAO;

	@Autowired
	private ItemCompraDAO itemCompraDAO;

	@Autowired
	private ItemVendaDAO itemVendaDAO;

	@Override
	public Produto criarNovoProduto() {
		Produto produto = new Produto();

		produto.setPeriodoMediaVenda(PeriodoEnum.SEMANAL);
		produto.setPeriodoProximoVencimento(PeriodoEnum.SEMANAL);

		produto.setQtdaMinima(0);
		produto.setQtdaMaxima(0);
		produto.setQtdaAtualEstoque(0);

		produto.setAtivo(true);

		return produto;
	}

	@Override
	public List<Produto> buscarProdutosPorGrupo(final GrupoProduto grupoProduto) {
		return produtoDAO.buscarProdutosPorGrupo(grupoProduto);
	}

	@Override
	public List<Produto> listarProdutosAtivosPorNome(String nome) {
		Produto produto = new Produto();
		produto.setAtivo(true);
		produto.setDescricao("%" + nome + "%");
		return produtoDAO.listarPorExemplo(produto);
	}

	@Override
	public List<ItemCompra> listarComprasProdutoPorPeriodo(
			final Produto produto, final Date dataInicial, final Date dataFinal) {
		return itemCompraDAO.listarComprasProdutoPorPeriodo(produto,
				dataInicial, dataFinal);
	}

	@Override
	public List<ItemVenda> listarVendasProdutoPorPeriodo(final Produto produto,
			final Date dataInicial, final Date dataFinal) {
		return itemVendaDAO.listarVendasProdutoPorPeriodo(produto, dataInicial,
				dataFinal);
	}

	@Override
	public List<Produto> buscarProdutosComEstoqueAbaixoLimiteMinino() {
		return produtoDAO.buscarProdutosComEstoqueAbaixoLimiteMinino(4);
	}

	@Override
	public List<ProdutoPorQuantidadeTO> buscarProdutosMaisVendidosNaSemana() {

		final Date dataAtual = Calendar.getInstance().getTime();
		final Date dataInicial = UtilData.obterPrimeiroDiaDaSemana(dataAtual);
		final Date dataFinal = UtilData.obterUltimoDiaDaSemana(dataAtual);

		final List<ItemVenda> listarItensVendas = itemVendaDAO
				.listarItensVendasPorPeriodo(dataInicial, dataFinal);

		final Map<Produto, Integer> mapaProduto = new HashMap<Produto, Integer>();

		for (ItemVenda itemVenda : listarItensVendas) {

			final Produto produto = itemVenda.getProduto();
			Integer qtda = mapaProduto.get(produto);

			if (qtda == null) {
				qtda = itemVenda.getQuantidade();
			} else {
				qtda += itemVenda.getQuantidade();
			}

			mapaProduto.put(produto, qtda);
		}

		final List<ProdutoPorQuantidadeTO> listaProdutoPorQtda = new ArrayList<ProdutoPorQuantidadeTO>();

		for (Produto produto : mapaProduto.keySet()) {
			listaProdutoPorQtda.add(new ProdutoPorQuantidadeTO(mapaProduto
					.get(produto), produto));
		}

		Collections.sort(listaProdutoPorQtda,
				new Comparator<ProdutoPorQuantidadeTO>() {

					@Override
					public int compare(
							ProdutoPorQuantidadeTO produtoPorQuantidadeTO,
							ProdutoPorQuantidadeTO produtoPorQuantidadeTO2) {

						return produtoPorQuantidadeTO2.getQuantidade()
								.compareTo(
										produtoPorQuantidadeTO.getQuantidade());
					}
				});

		return listaProdutoPorQtda;
	}

	@Override
	public GenericDAO<Produto> getDAO() {
		return produtoDAO;
	}
}
